package com.validator;

import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.validator.FacesValidator;
import javax.faces.validator.Validator;
import javax.faces.validator.ValidatorException;

/**
 * Classe de validation d'un code postal.
 * @author Cyril Schumacher
 */
@FacesValidator("zipCodeValidator")
public class ZipCodeValidator implements Validator {
    // <editor-fold defaultstate="collapsed" desc="Constantes.">
    /**
     * Modèle pour le code postal.
     */
    private final static String ZIPCODE_PATTERN = "^(F-)?((2[A|B])|[0-9]{2})[0-9]{3}$";
    /**
     * Modèle compilé.
     */
    private final static Pattern ZIPCODE_COMPILED_PATTERN = Pattern.compile(ZIPCODE_PATTERN);
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="Méthodes.">
    /**
     * Lève un message d'erreur.
     *
     * @param summary Message d'erreur.
     * @param details Détails de l'erreur.
     */
    private void _CreateErrorMessage(String summary, String details) {
        FacesMessage msg = new FacesMessage(summary, details);
        msg.setSeverity(FacesMessage.SEVERITY_ERROR);
        throw new ValidatorException(msg);
    }

    /**
     * Détermine si une valeur corresponds à un code postal valide.
     * @param value Valeur.
     * @return Retourne TRUE si c'est une adresse e-mail valide, FALSe sinon.
     */
    private Boolean _IsValidZipCode(String value) {
        Matcher matcher = ZIPCODE_COMPILED_PATTERN.matcher(value);
        return matcher.matches() == true;
    }
    /**
     * Valide la valeur.
     *
     * @param context Informations contextuelles associées au traitement de la
     * requête.
     * @param component Composant graphique.
     * @param value Valeur.
     * @throws ValidatorException
     */
    @Override
    public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
        // Vérifie si la valeur est de type chaîne de caractère et non-vide.
        if (value instanceof String) {
            if (value.equals("") == false) {
                // Analyse la chaîne de caractère pour déterminer si c'est une
                // adresse e-mail valide.
                if (_IsValidZipCode(value.toString()) == false) {
                    _CreateErrorMessage("Code postal invalide.",
                            "La valeur ne corresponds pas à un code postal.");
                }
            } else {
                _CreateErrorMessage("Aucune valeur.",
                        "Une valeur est attendue pour le code postal.");
            }
        }
    }
    // </editor-fold>
}
